package org.jprobe.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;

import org.jprobe.JavaProject;
import org.jprobe.JavaProjectInterface;
import org.jprobe.junit.AbstractJUnitGenerator;
/**
 * project view
 * @author Hussain Al-Mutawa
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("serial")
public class ProjectView extends JPanel implements ActionListener{

	private transient final JPanel pnl1,pnl3;
	private transient final JLabel lbl1,lbl2,lbl3,lbl4,lbl5,lbl6,lbl7,lbl8,lbl9;
	private transient final JTextField txt1,txt2,txt3,txt4,txt5,txt6;
	private transient final JTextArea txa1;
	private transient final JScrollPane scp1;
	private transient final JButton btn1,btn2,btn3,btn4;
	private transient final JProgressBar pbr1;
	private transient JavaProjectInterface javaProject;
	
	public ProjectView() {
		super();
		this.pnl1 = new JPanel();
		this.pnl3 = new JPanel();
		pnl3.setLayout(new BorderLayout());

		this.pbr1 = new JProgressBar();
		//pbr1.setBorder(BorderFactory.createEmptyBorder(12,12,12,12));
		//pbr1.setValue(55);

		this.lbl1 = new JLabel("Project Directory:");
		this.lbl2 = new JLabel("Packages:");
		this.lbl3 = new JLabel("Classes:");
		this.lbl4 = new JLabel("Test coverage:");
		this.lbl5 = new JLabel("Test success rate:");
		this.lbl6 = new JLabel("Test Cases:");
		this.lbl7 = new JLabel("Tests generation progress:");
		this.lbl8 = new JLabel("Terminal:");
		this.lbl9 = new JLabel("*");

		this.txt1 = new JTextField();
		this.txt2 = new JTextField();
		this.txt3 = new JTextField();
		this.txt4 = new JTextField();
		this.txt5 = new JTextField();
		this.txt6 = new JTextField();

		this.txa1 = new JTextArea();
		this.scp1 = new JScrollPane(txa1,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

		this.btn1=new JButton("Open project");
		this.btn2=new JButton("build.xml");
		this.btn3=new JButton("Export results");
		this.btn4=new JButton("jProbe it");

		this.txa1.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
		this.pnl3.add(scp1,BorderLayout.CENTER);

		this.addControls(pnl1, new JComponent[]{
				lbl1,lbl2,lbl3,lbl4,lbl5,lbl6,lbl7,lbl8,lbl9,
				txt1,txt2,txt3,txt4,txt5,txt6,
				btn1,btn2,btn3,btn4,
				pbr1,pnl3
		});

		btn1.setToolTipText("Change the existing project");
		btn2.setToolTipText("Run ANT build script");
		btn3.setToolTipText("Export project statistics to text file");
		btn4.setToolTipText("Automatically generate test cases for this project");

		this.setLayout(new BorderLayout());
		this.add(pnl1,BorderLayout.CENTER);
		this.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		this.pnl1.setBorder(BorderFactory.createEtchedBorder());
		this.pnl1.setLayout(null);
		loc(lbl1,10 ,10,120,20);loc(txt1,130,10,330,20);loc(btn1,470,10,150,20);
		loc(btn2,470,60,150,20);
		loc(btn3,470,85,150,20);
		loc(btn4,470,110,150,20);
		loc(lbl2,10 ,35,120,20);loc(txt2,130,35,50,20);loc(lbl4,200 ,35,120,20);loc(txt4,340,35,50,20);
		loc(lbl3,10 ,60,120,20);loc(txt3,130,60,50,20);loc(lbl5,200 ,60,120,20);loc(txt5,340,60,50,20);
		loc(lbl6,10 ,85,120,20);loc(txt6,130,85,50,20);
		loc(lbl7,10 ,120,610,20);
		loc(pbr1,10 ,140,610,20);
		loc(lbl9,10 ,165,610,20);
		loc(lbl8,10 ,200,610,20);
		loc(pnl3,10 ,220,610,150);

		this.setTextLocked(new JTextComponent[]{txt1,txt2,txt3,txt4,txt5,txt6,txa1});
		this.btn2.setEnabled(false);
		this.btn3.setEnabled(false);
		this.lbl9.setForeground(Color.darkGray);
	}

	private void loc(JComponent control,int x,int y,int w,int h){
		control.setBounds(x,y,w,h);
	}
	private void addControls(JComponent parent,JComponent[]components){
		for(final JComponent component:components){
			parent.add(component);
			if(component.getClass()==JButton.class){
				((JButton)component).addActionListener(this);
			}
		}
	}
	private void setTextLocked(final JTextComponent[] txts){
		for(final JTextComponent txt:txts){
			txt.setForeground(Color.blue);
			txt.setEditable(false);
			txt.setCursor(new Cursor(Cursor.TEXT_CURSOR));
		}
	}
	@Override
	public void actionPerformed(final ActionEvent ae) {
		try{
			doAction(ae);
		}catch(Throwable throwable){
			JOptionPane.showMessageDialog(this, throwable.getMessage());
		}
	}

	private void doAction(final ActionEvent ae) throws Exception{
		final String action = ((JButton)ae.getSource()).getText();
		if("Open project".equals(action)){
			final JFileChooser fileChooser = new JFileChooser();
			fileChooser.setCurrentDirectory(new File("."));
			fileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
			final int result = fileChooser.showDialog(null, "Choose project");

			if(result==JFileChooser.APPROVE_OPTION){
				try {
					this.txt1.setText(fileChooser.getSelectedFile().getCanonicalPath());
					javaProject = new JavaProject(new File(txt1.getText()));
					new Thread(){public void run(){
						try {
							javaProject.load();
						} catch (Exception e) {
							throw new RuntimeException(e);
						}
						txt2.setText(javaProject.getPackages().length+"");
						txt3.setText(javaProject.getClasses().length+"");			
						refresh(new JComponent[]{txt2,txt3});
					}}.start();
				} catch (IOException ioe) {
					txt2.setText("");
					throw new RuntimeException(ioe);
				}
			}
			
			
			
		}else if("jProbe it".equals(action)){
			if(javaProject==null){
				throw new RuntimeException("project has not been selected yet");
			}
			new Thread(
					new AbstractJUnitGenerator(javaProject) {
						@Override
						public void processStarted() {
							pbr1.setMaximum(getTotalTransactions());
						}

						@Override
						public void processCompleted() {
							pbr1.setValue(getTotalTransactions());
						}

						@Override
						public void progressChanged(int progress) {
							//synchronized(this){
							lbl9.setText(getCurrentItem());
							pbr1.setValue(progress);
							refresh(new JComponent[]{pbr1,lbl9});
							out((100*progress/getTotalTransactions())+"%");
							//}
						}
						@Override
						public void out(String message) {
							txa1.append(message+'\n');
							txa1.setSelectionStart(txa1.getText().length());
						}
						@Override
						public void err(String message) {
							txa1.append("ERROR : "+message+'\n');
							txa1.setSelectionStart(txa1.getText().length());
						}
						@Override
						public int getTimeOut() {
							return 4;
						}
					}).start();
		}else{
			System.err.println("button ["+action+"] action was not implemented");
			//System.exit(0);
		}		
	}

	protected void refresh(final JComponent[] comps) {
		for(final JComponent comp:comps){
		comp.revalidate();
		comp.invalidate();
		comp.repaint();
		}
	}



}